/*
 * Copyright (c) 2016, Roman Meyta <theshrodingerscat@gmail.com>
 * Copyright (c) 2020-2021 https://gitee.com/fsfzp888
 * All rights reserved
 */

#ifndef WEBCAM_WINDOW_HXX
#define WEBCAM_WINDOW_HXX

#include <QImage>
#include <QMainWindow>
#include <QMutex>
#include <QSettings>

#include "AVILib.h"
#include "ImageFormats.h"

class QLabel;
class VideoDevice;
class VideoCapture;
class QHBoxLayout;
class QVBoxLayout;
class QPushButton;
class QLineEdit;
class QComboBox;
class QGroupBox;
class QSplitter;

/**
 * @brief Main window class
 */
class WebcamWindow : public QMainWindow
{
    Q_OBJECT

  public:
    /**
     * @brief Constructor
     *
     * @param parent
     */
    WebcamWindow(QWidget *parent = nullptr);

    /**
     * @brief Destructor
     */
    virtual ~WebcamWindow();

    /**
     * @brief Process new video frame
     *
     * @param data
     * @param len
     * @param device
     */
    void processFrame(const unsigned char *data, int len, VideoDevice *device);

    /**
     * @brief Process new still frame
     *
     * @param data
     * @param len
     * @param device
     */
    void processStillFrame(const unsigned char *data, int len, VideoDevice *device);

    void writeQImageToFile(const QImage &img);

    inline void setAppDirPath(QString dir_path) noexcept { m_appDirPath = dir_path; }

  protected:
    void resizeEvent(QResizeEvent* ev) override;

  private Q_SLOTS:
    /**
     * @brief Render last frame
     */
    void presentFrame();

    /**
     * @brief Change video resolution
     *
     * @param int resolution number
     */
    void changeResolution(int resolutionNum);

    /**
     * @brief Change video device
     *
     * @param int device number
     */
    void changeDevice(int deviceNum);

    /**
     * @brief Flip frame
     */
    void flipFrame();

    /**
     * @brief Start capture
     */
    void startCapture();

    /**
     * @brief Stop capture
     */
    void stopCapture();

    void incCaptureCnt();
    void incThreeCaptureCnt();

    /**
     * Browse file
     */
    void browse();

  private:
    /**
     * @brief Viewport
     */
    QLabel *m_viewport;

    /**
     * @brief Frame mutex
     */
    QMutex m_frameMutex;

    /**
     * @brief Current frame
     */
    QImage m_frame;

    /**
     * @brief Layout for control widgets
     */
    QVBoxLayout *m_controlLayout;

    /**
     * @brief Group of control widgets
     */
    QGroupBox *m_controlGroup;

    /**
     * @brief Main layout
     */
    QHBoxLayout *m_windowLayout;

    /**
     * @brief Main group
     */
    QGroupBox *m_windowGroup;

    /**
     * @brief Start button
     */
    QPushButton *m_startButton;

    /**
     * @brief Stop button
     */
    QPushButton *m_stopButton;

    /**
     * @brief Software capture button
     */
    QPushButton *m_captureButton;

    /**
     * @brief Software capture three photo button
     */
    QPushButton *m_captureThreeButton;

    /**
     * @brief Hint
     */
    QLabel *m_devicesLabel;

    /**
     * @brief List of available devices
     */
    QComboBox *m_devices;

    /**
     * @brief Hint
     */
    QLabel *m_resolutionsLabel;

    /**
     * @brief List of available resolutions
     */
    QComboBox *m_resolutions;

    /**
     * @brief Hint
     */
    QLabel *m_directoryLabel;

    /**
     * @brief Output directory
     */
    QLineEdit *m_directory;

    /**
     * @brief Browse button
     */
    QPushButton *m_browserButton;

    /**
     * @brief Name label
     */
    QLabel *m_nameLabel;

    /**
     * @brief User name input
     */
    QLineEdit *m_name;

    /**
     * @brief file directory layout
     */
    QHBoxLayout *m_browserDirectoryLayout;

    /**
     * @brief Devices group
     */
    QGroupBox *m_devicesGroup;

    /**
     * @brief Devices layout
     */
    QVBoxLayout *m_devicesLayout;

    /**
     * @brief Vertical splitter
     */
    QSplitter *m_vsplitter;

    /**
     * @brief Flip button
     */
    //QPushButton *m_flipButton;

    /**
     * @brief Video controller
     */
    VideoCapture *m_videoCapture;

    /**
     * @brief Dir path
     */
    QString m_appDirPath;

    /**
     * QImage converter
     */
    QImageMaker m_makeQImage;

    /**
     * @brief AVI video writer
     */
    avilib::AviWriter *m_aviWriter;

    /**
     * @brief Current settings
     */
    QSettings m_settings;

    /**
     * Photo capture counter
     */
    int m_photoCount;

    /**
     * @brief Capturing flag
     */
    bool m_isCapturing;

    /**
     * @brief Is stop flag
     */
    bool m_isStop;

    /**
     * @brief Flipping flag
     */
    bool m_isFlipped;
};

#endif  // WEBCAM_WINDOW_HXX
